package sisdroid.client;

import java.util.*;

import sisdroid.client.model.Location;

import android.app.Activity;
import android.bluetooth.*;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import static android.bluetooth.BluetoothAdapter.STATE_ON;
import static android.bluetooth.BluetoothDevice.*;

public class BluetoothDiscoverer implements NetDiscoverer
{

	Activity 									caller;
	Set<sisdroid.client.model.Location> 		netIds;
	BluetoothAdapter 							bt;
	boolean										scanInProgress;
	
	public BluetoothDiscoverer( Activity caller )
	{
		this.caller		= caller;
		
		netIds			= new HashSet<sisdroid.client.model.Location>();
		bt				= BluetoothAdapter.getDefaultAdapter();
		scanInProgress	= false;
		
		if ( bt == null ) return;

		
		// Action when phone find a remote device
		IntentFilter filter = new IntentFilter( ACTION_FOUND );
		
		BroadcastReceiver deviceFoundReceiver = new BroadcastReceiver()
		{       
			@Override
			public void onReceive(Context arg0, Intent intent)
			{
				BluetoothDevice device = intent.getParcelableExtra( EXTRA_DEVICE );
				String strMac = device.getAddress();
				if ( ! netIds.contains( strMac ) )
				{
					netIds.add( new Location("bt" , device.getAddress() ) );
				}
			 }
		};
		
		this.caller.registerReceiver( deviceFoundReceiver, filter );
		
		
		filter = new IntentFilter( BluetoothAdapter.ACTION_DISCOVERY_STARTED );
		
		BroadcastReceiver scanStartedReceiver = new BroadcastReceiver()
		{       
			@Override
			public void onReceive(Context arg0, Intent intent)
			{
				scanInProgress = true;
			}
		};
		
		this.caller.registerReceiver( scanStartedReceiver, filter );
		
		filter = new IntentFilter( BluetoothAdapter.ACTION_DISCOVERY_FINISHED );
		
		BroadcastReceiver scanFinnisedReceiver = new BroadcastReceiver()
		{       
			@Override
			public void onReceive(Context arg0, Intent intent)
			{
				scanInProgress = false;
			}
		};
		
		this.caller.registerReceiver( scanFinnisedReceiver, filter );
		try
		{
			bt.startDiscovery();
			scanInProgress = true;
		}
		catch ( Exception e )
		{
			System.out.println( e.toString() );  
		}
	}
	
	@Override
	public Set<sisdroid.client.model.Location> getNetIDS()
	{
		Set<sisdroid.client.model.Location> result = new HashSet<sisdroid.client.model.Location>();
		// Only scan in case of enabled BT hardware
		// bt is null, well BT is not supported by device.
		if ( bt != null && bt.getState() == STATE_ON )
		{
			
			// Sleep max ten secs.
			
			int iSleepTime = 100; //ms
			int iMaxCycles = 100;
			int iCycles = 0;
			
			
			
			while ( iCycles < iMaxCycles && scanInProgress )
			{
				iCycles ++;
				try
				{
					Thread.sleep( iSleepTime );
				}
				catch (InterruptedException e)
				{
					// TODO we ignore this event so far.
					e.printStackTrace();
				}
			}
			
			// Why not just return netIds?
			// consumers could change our internal Set then.
			result.addAll( netIds );
		}

		return result;
	}

}
